package com.atguigu.mq.listener;


import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;

import java.io.IOException;


@Component
@Slf4j
public class ConsumerMessageListener {

    //利用注解的方式创建交换机和队列和绑定

    //监听方法


    //队列一旦创建，属性信息不能修改。只能删除重建。
    @RabbitListener(
            //设置绑定关系
            bindings = { @QueueBinding(
                    //name:指定队列名称    durable=true是否支持持久化    exclusive=false是否排他队列(只限当前连接使用当连接关闭队列自动删除)
                    //autodelete=false是否自动删除  长时间不使用一直空闲那么服务器会自动删除队列
                    //declare=true队列不在就创建队存在就直接使用  注意队列属性必须一致不能修改,修改只能删除队列重新创建
                    value = @Queue(name = "queue.order", durable = "true", exclusive = "false", autoDelete = "false", declare = "true",
                    //argument设置超时时间的 name="x-message-ttl" value="20000"队列总体超时设置
                    arguments = { @Argument(name = "x-message-ttl", value = "20000", type = "java.lang.Integer")

                    }),
                    exchange = @Exchange(name = "exchange.direct.order", durable = "true",
                            //internal是否只为内部交换机,内部交换机只给服务器用不能用于微服
                            //type 类型  :direct,topic,fanout,headers
                            type = ExchangeTypes.DIRECT, autoDelete = "false", internal = "false", declare = "true"),
                    key = {"order"}
            )}
    )
    public void messageHandler(String msg, Message message, Channel channel) throws IOException {

        //消息的唯一标识相当于id
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        try {
            log.info("msg="+msg);
            log.info("message="+message);
            //处理完后睡眠0.5秒
            Thread.sleep(50);




            //模拟一个异常
            //int a=1/0;
            //ture 自动确认消息效率高,  false手动确认消息 并且要一个一个的确认效率低
            channel.basicAck(deliveryTag,false);
        } catch (Exception e) {
            //消息是否重复投递
            Boolean redelivered = message.getMessageProperties().getRedelivered();

            if(!redelivered){
                //不是重复投递,第一次投递让其回到原有队列
                channel.basicReject(deliveryTag,true);
                log.info(String.valueOf(deliveryTag));


            }else {
                //重复投递,不确认消息还不能返回到原队列,要么消息丢失,要么去死信队列
                channel.basicNack(deliveryTag,false,false);
                log.info(String.valueOf(deliveryTag));

            }

        }


    }
}

